<script lang="ts" setup>
import { computed } from '@vue/reactivity';
import { reactive, watch } from 'vue';
// javascript
interface IEmit {
  /**
   * 分页事件
   */
  (e: 'page-change', value: number): void
  /**
   * 搜索按钮事件
   */
  (e: 'search'): void
  /**
   * 当前页码双向绑定
   */
  (e: 'update:current', value: number): void
}

interface IProps {
  /**
   * 是否显示分页
   */
  showPage?: boolean
  /**
   * 当前页面 vmodel
   */
  current?: number
  /**
   * 总条数
   */
  total?: number
  /**
   * 每页大小 默认 20
   */
  size?: number
  /**
   * 是否显示过滤表单
   */
  showFilter?: boolean
}

const emits = defineEmits<IEmit>();
const props = withDefaults(defineProps<IProps>(), {
  current: 1,
  total: 0,
  size: 20,
  showPage: true,
  showFilter: true
});
const page = reactive({
  current: props.current,
  total: props.total,
  size: props.size
});

// 搜索点击事件
const onSearch = () => {
  emits('search');
}

// 分页点击
const onPageChange = () => {
  emits('update:current', page.current);
  emits('page-change', page.current);
}

// 计算页数
const cpdPageCount = computed(() => {
  const count = Math.ceil(page.total / page.size);
  return isNaN(count) ? 0 : count;
});

watch([() => props.current, () => props.size, () => props.total], () => {
  page.current = props.current;
  page.size = props.size;
  page.total = props.total;
});

</script>

<!-- 共用表格模板组件 -->
<template>
  <section class="table-layout-container">
    <div class="filter-box" v-if="showFilter">
      <a-card>
        <a-form class="filter-form" layout="inline" @finish="onSearch">
          <div>
            <slot name="filter-form"></slot>
          </div>
          <div>
            <template v-if="!$slots['filter-btn']">
              <a-button type="primary" html-type="reset">
                <template #icon><SearchOutlined /></template>
                搜索
              </a-button>
              <a-button type="default" html-type="reset">重置</a-button>
            </template>
            <template v-else>
              <slot name="filter-btn"></slot>
            </template>
          </div>
        </a-form>
      </a-card>
    </div>

    <div class="table-box">
      <div class="table-header">
        <section class="title">
          <unordered-list-outlined />
          <span>数据列表</span>
        </section>
        <section class="btn-box">
          <slot name="table-header-btn"></slot>
        </section>
      </div>
      <slot name="table-content"></slot>
    </div>

    <div class="page-box" v-if="showPage">
      <p>{{ page.total }} 条数据 第 {{ page.current }} 页 共 {{ cpdPageCount }} 页</p>
      <a-pagination 
      v-model:current="page.current" 
      v-model:page-size="page.size"
      :total="page.total"
      show-quick-jumper 
      @change="onPageChange" />
    </div>
  </section>
</template>

<style lang="less" scoped>
// less
.table-layout-container {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.filter-box {
  margin-bottom: 10px;
}
.filter-form {
  > div {
    display: flex;
    flex-wrap: wrap;

    &:first-child {
      flex: 1;

      :deep(.ant-form-item) {
        // margin-bottom: 10px;

        .ant-form-item-label {
          width: 110px;
          text-align: right;
        }
      }
    }

    &:last-child {
      width: 200px;
      display: flex;
      align-items: center;
      justify-content: flex-end;
      border-left: 1px solid #F4F4F4;

      .ant-btn {
        &:not(:first-child) {
          margin-left: 10px;
        }
      }
    }
  }
}

.table-box {
  flex: 1;
  background-color:#fff;
  padding: 16px;
  overflow: auto;

  :deep(.ant-table-wrapper) {
    tbody {
      td {
        padding-top: 15px;
        padding-bottom: 15px;
        align-items: center;
        vertical-align: middle;
      }
    }

    .ant-spin-nested-loading {
      > div:first-child {
        position: absolute;
        width: 100%;
        height: 100%;
      }
    }
  }

  .table-header {
    height: 40px;
    margin-bottom: 10px;
    display: flex;
    align-items: center;
    justify-content: space-between;

    section.title {
      > span {
        margin-right: 5px;
      }
    }

    :deep(.btn-box) {
      .ant-btn {
        margin-left: 10px;
      }
    }
  }
}
.page-box {
  height: 60px;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding-right: 16px;
  background-color: #fff;

  > p {
    margin-right: 20px;
  }
}
</style>